package com.markhsiu.minimq.message;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import com.markhsiu.minimq.core.constant.ConstantUtil;
import com.markhsiu.minimq.message.constant.MessageCmdEnum;
import com.markhsiu.minimq.message.constant.MessageSourceEnum;
import com.markhsiu.minimq.serialize.protostuff.ProtostuffCodec;

/**
 * 远程传输消息体
 * 
 * @author Mark Hsiu
 *
 */
public class Message implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3829397244075305769L;

	private transient static final String key_consumerID = "consumerID";
	private transient static final String default_topic = "topic";
	
	private String messageID;// 消息ID
	private MessageSourceEnum source;// 消息来源
	private MessageSourceEnum target;// 消息目标
	private MessageCmdEnum cmd;// 消息命令
	private String topic;// 消息主题
	private Map<String, Object> head = new HashMap<>();// 消息头
	private byte[] body;// 消息内容
	private long timestamp;// 时间戳
	
	public String getTopic() {
		if (topic == null) {
			topic = default_topic;
		}
		return topic;
	}

	public void setTopic(String topic) {
		this.topic = topic;
	}

	public String getMessageID() {
		return messageID;
	}

	public void setMessageID(String messageID) {
		this.messageID = messageID;
	}

	public long getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}

	public MessageSourceEnum getSource() {
		return source;
	}

	public void setSource(MessageSourceEnum source) {
		this.source = source;
	}

	public MessageSourceEnum getTarget() {
		return target;
	}

	public void setTarget(MessageSourceEnum target) {
		this.target = target;
	}

	public MessageCmdEnum getCmd() {
		return cmd;
	}

	public void setCmd(MessageCmdEnum cmd) {
		this.cmd = cmd;
	}

	public String getHeadString(String key) {
		return (String) head.get(key);
	}

	public Integer getHeadInteger(String key) {
		return (Integer) head.get(key);
	}

	public void setConsumerID(String consumerID) {
		head.put(key_consumerID, consumerID);
	}

	public String getConsumerID() {
		return getHeadString(key_consumerID);
	}

	public byte[] getBody() {
		return body;
	}

	public void setBody(byte[] body) {
		this.body = body;
	}
	
	public byte[] buildByte() {
		try {
			return ProtostuffCodec.OneInstance().serialize(this);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static Message restore(byte[] data) {
		try {
			return ProtostuffCodec.OneInstance().deserialize(data);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	

	public static Message newInstance() {
		Message message = new Message();
		message.setMessageID(ConstantUtil.UUID());
		message.setTimestamp(System.currentTimeMillis());
		return message;
	}

	public  static Message newSuccess(Message req) {
		Message message = new Message();
		message.setCmd(MessageCmdEnum.SUCCESS);
		message.setMessageID(req.getMessageID());
		message.setTimestamp(System.currentTimeMillis());
		return message;
	}

	public static Message newFail(Message req) {
		Message message = new Message();
		message.setCmd(MessageCmdEnum.FAIL);
		message.setMessageID(req.getMessageID());
		message.setTimestamp(System.currentTimeMillis());
		return message;
	}

	public static Message newError(Message req) {
		Message message = new Message();
		message.setCmd(MessageCmdEnum.ERROR);
		message.setMessageID(req.getMessageID());
		message.setTimestamp(System.currentTimeMillis());
		System.out.println(message + " newError");
		return message;
	}

	@Override
	public String toString() {
		return String.format("cmd:%s topic:%s  ID:%s  source:%s  target:%s ", cmd, topic, messageID, source, target);
	}

}
